package com.rw.coco.util;

import com.rw.coco.api.data.TransactionSwitch;
import com.rw.coco.api.data.exception.TransactionException;
import com.rw.coco.handler.message.event.CocoMessageEvent;

import java.util.UUID;

/**
 * 开启事务工具类
 */
public class TransactionUtil {
    /**
     * 开启事务，执行事务代码
     *
     * @param transactionSwitch 事务开关
     * @param action            事务内做的动作
     */
    public static <T> T runWithResult(TransactionSwitch transactionSwitch, TransactionFunction<T> action) {
        // 生成uuid
        String uuid = UUID.randomUUID().toString();
        try {
            // 开启，事务，并且执行事务内容
            transactionSwitch.begin(uuid);
            T result = action.action();

            // 执行成功，提交事务
            transactionSwitch.commit(uuid);

            return result;
        } catch (Throwable e) {
            // 未知错误，回滚事务，抛出异常
            transactionSwitch.rollback(uuid);
            throw new TransactionException(e);
        }
    }

    /**
     * 开启事务，执行事务代码
     *
     * @param cocoMessageEvent 可可消息事件
     * @param action           事务内做的动作
     */
    public static <T> T runWithResult(CocoMessageEvent cocoMessageEvent, TransactionFunction<T> action) {
        return runWithResult(cocoMessageEvent.getPersistenceMapper().getTransactionSwitch(), action);
    }

    /**
     * 开启事务，执行事务代码
     *
     * @param transactionSwitch 事务开关
     * @param action            事务内做的动作
     */
    public static void run(TransactionSwitch transactionSwitch, TransactionAction action) {
        // 生成uuid
        String uuid = UUID.randomUUID().toString();
        try {
            // 开启，事务，并且执行事务内容
            transactionSwitch.begin(uuid);
            action.action();

            // 执行成功，提交事务
            transactionSwitch.commit(uuid);
        } catch (Throwable e) {
            // 未知错误，回滚事务，抛出异常
            transactionSwitch.rollback(uuid);
            throw new TransactionException(e);
        }
    }

    /**
     * 开启事务，执行事务代码
     *
     * @param cocoMessageEvent 可可消息事件
     * @param action           事务内做的动作
     */
    public static void run(CocoMessageEvent cocoMessageEvent, TransactionAction action) {
        run(cocoMessageEvent.getPersistenceMapper().getTransactionSwitch(), action);
    }

    /**
     * 开始事务
     */
    public static void begin(CocoMessageEvent messageEvent, String uuid) {
        messageEvent.getPersistenceMapper().getTransactionSwitch().begin(uuid);
    }

    /**
     * 回滚事务
     */
    public static void rollback(CocoMessageEvent messageEvent, String uuid) {
        messageEvent.getPersistenceMapper().getTransactionSwitch().rollback(uuid);
    }

    /**
     * 提交事务
     */
    public static void commit(CocoMessageEvent messageEvent, String uuid) {
        messageEvent.getPersistenceMapper().getTransactionSwitch().commit(uuid);
    }
}
